package com.ecp.commons.file;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletInputStream;

public class FilePart extends Part {

	private String				fileName;
	private String				filePath;
	private String				contentType;
	private PartInputStream		partInput;
	private FileRenamePolicy	policy;
	private String				tempFileName;

	FilePart(String name, ServletInputStream in, String boundary, String contentType, String fileName, String filePath)
			throws IOException {
		super(name);
		this.fileName = fileName;
		this.filePath = filePath;
		this.contentType = contentType;
		partInput = new PartInputStream(in, boundary);
	}

	public void setRenamePolicy(FileRenamePolicy policy) {
		this.policy = policy;
	}

	public String getFileName() {
		return fileName;
	}

	public String getTempFileName() {
		return this.tempFileName;
	}

	public String getFilePath() {
		return filePath;
	}

	public String getContentType() {
		return contentType;
	}

	public InputStream getInputStream() {
		return partInput;
	}

	public long writeTo(File fileOrDirectory) throws IOException {
		long written = 0;
		OutputStream fileOut = null;
		File file;
		try {
			if (fileName != null) {

				if (fileOrDirectory.isDirectory()) {
					try {
						fileName = new String(fileName.getBytes("iso-8859-1"), "GBK");
					} catch (java.io.UnsupportedEncodingException e) {
						e.printStackTrace();
					}
					TempFileName temp = new TempFileName(fileName);
					this.tempFileName = temp.getTempFileName();
					file = new File(fileOrDirectory, temp.getTempFileName()); 
				} else {
					file = fileOrDirectory;
				}
				if (policy != null) {
					file = policy.rename(file);
					fileName = file.getName();
					this.tempFileName = file.getPath();
				}
				fileOut = new BufferedOutputStream(new FileOutputStream(file));
				written = write(fileOut);

			}
		} finally {
			if (fileOut != null) {
				fileOut.close();
			}
		}

		return written;
	}

	public long writeTo(OutputStream out) throws IOException {
		long size = 0;
		// Only do something if this part contains a file
		if (fileName != null) {
			// Write it out
			size = write(out);
		}
		return size;
	}

	long write(OutputStream out) throws IOException {
		// decode macbinary if this was sent
		if (contentType.equals("application/x-macbinary")) {
			out = new MacBinaryDecoderOutputStream(out);
		}
		long size = 0;
		int read;
		byte[] buf = new byte[8 * 1024];
		while ((read = partInput.read(buf)) != -1) {
			out.write(buf, 0, read);
			size += read;
		}
		return size;
	}

	public boolean isFile() {
		return true;
	}
}
